namespace Destra.Common.Caching
{
    /// <summary>
    /// Abstract class to be inherited in all custom caching classes.
    /// </summary>
    public abstract class CacheBase
    {

        #region Fields

        private string _applicationName;
        private string _cachePath = System.IO.Path.GetTempPath();

        #endregion

        public CacheBase()
        {
            // create our config class to set some properties.
            ApplicationName = CacheConfiguration.Instance.ApplicationName;
            CachePath = System.IO.Path.Combine(CacheConfiguration.Instance.RootPath, CacheConfiguration.Instance.ApplicationName);

            // The CachePath is the DFS path where each application will write an txt file. The txt file
            // is used to keep each cache in sync. We use a FileWatcher on the directory and remove cached
            // items on other servers if they previously held an item in a cache (for a table).
            if (!System.IO.Directory.Exists(CachePath))
            {
                System.IO.Directory.CreateDirectory(CachePath);
            }
        }

        /// <summary>
        /// The name of the application for using the cache. The application will be combined with 
        /// the CachePath to form Drive:\CachePath\ApplicationName\[Temporary-File-Name].txt.
        /// </summary>
        public string ApplicationName
        {
            get { return _applicationName; }
            set { _applicationName = value; }
        }

        /// <summary>
        /// The base path to store the cache files.
        /// </summary>
        public string CachePath
        {
            get { return _cachePath; }
            set { _cachePath = value; }
        }

        /// <summary>
        /// Retrieves the specified item from the Destra.Services.Common.Caching.CacheBase.Cache object.
        /// </summary>
        /// <param name="key">The identifier for the cache item to retrieve.</param>
        /// <returns>The retrieved cache item, or null if the key is not found.</returns>
        public object this[string key]
        {
            get { return Cache[key]; }
        }

        /// <summary>
        /// Retrieves the specified item from the Destra.Services.Common.Caching.CacheBase.Cache object.
        /// </summary>
        /// <param name="key">The identifier for the cache item to retrieve.</param>
        /// <returns>The retrieved cache item, or null if the key is not found.</returns>
        public object Get(string key)
        {
            return Cache[key];
        }

        /// <summary>
        /// Used to remove all items from the cache. It should be noted that this does not reset the
        /// cache on any other servers and should only be used during debugging.
        /// </summary>
        public void Reset()
        {
            System.Collections.IDictionaryEnumerator d = System.Web.HttpRuntime.Cache.GetEnumerator();
            while (d.MoveNext())
            {
                System.Web.HttpRuntime.Cache.Remove(d.Key.ToString());
            }
        }

        /// <summary>
        /// Implements the cache for an application.
        /// </summary>
        protected System.Web.Caching.Cache Cache
        {
            get { return System.Web.HttpRuntime.Cache; }
        }

        /// <summary>
        /// Checks to see if a top level cache key exists. It will not check if the key
        /// exists in any cache dependencies.
        /// </summary>
        /// <param name="key">The identifier for the cache item to check.</param>
        /// <returns>True if the top level key exists in the cache.</returns>
        public bool Contains(string key)
        {
            return (Cache[key] != null);
        }

    }
}